using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Common;

namespace NBear.Data
{
    public abstract class DbProvider
    {
        #region Protected Members

        protected System.Data.Common.DbProviderFactory dbProviderFactory;
        protected DbConnectionStringBuilder dbConnStrBuilder;

        /// <summary>
        /// Initializes a new instance of the <see cref="T:DbProvider"/> class.
        /// </summary>
        /// <param name="connStr">The conn STR.</param>
        /// <param name="dbProviderFactory">The db provider factory.</param>
        protected DbProvider(string connStr, System.Data.Common.DbProviderFactory dbProviderFactory)
        {
            dbConnStrBuilder = new DbConnectionStringBuilder();
            dbConnStrBuilder.ConnectionString = connStr;
            this.dbProviderFactory = dbProviderFactory;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the connection string.
        /// </summary>
        /// <value>The connection string.</value>
        public string ConnectionString
        {
            get
            {
                return dbConnStrBuilder.ConnectionString;
            }
        }

        /// <summary>
        /// Gets the db provider factory.
        /// </summary>
        /// <value>The db provider factory.</value>
        public System.Data.Common.DbProviderFactory DbProviderFactory
        {
            get
            {
                return dbProviderFactory;
            }
        }

        #endregion

        #region Abstract Members

        public abstract void AdjustParameter(DbParameter param);

        /// <summary>
        /// <para>When overridden in a derived class, creates an <see cref="IPageSplit"/> for a SQL page splitable select query.</para>
        /// </summary>
        /// <param name="selectStatement"><para>The text of the basic select query for all rows.</para></param>        
        /// <param name="keyColumn"><para>The sigle main key of the query.</para></param>        
        /// <param name="paramValues"><para>The param values of the query.</para></param>        
        /// <returns><para>The <see cref="IPageSplit"/> for the SQL query.</para></returns>        
        public abstract IPageSplit CreatePageSplit(Database db, string selectStatement, string keyColumn, object[] paramValues);

        /// <summary>
        /// Creates the SQL statement factory.
        /// </summary>
        /// <returns></returns>
        public abstract IStatementFactory CreateStatementFactory();

        /// <summary>
        /// Discovers params from SQL text.
        /// </summary>
        /// <param name="where">The full or part of SQL text.</param>
        /// <returns>The discovered params.</returns>
        public abstract string[] DiscoverParams(string sql);

        /// <summary>
        /// Builds the name of the parameter.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        public abstract string BuildParameterName(string name);

        /// <summary>
        /// Builds the name of the column.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        public abstract string BuildColumnName(string name);

        public abstract string SelectLastInsertedRowAutoIDStatement
        {
            get;
        }

        public abstract bool SupportADO20Transaction
        {
            get;
        }

        public abstract string FilterSelectSqlBeginEnd(string sql);

        public abstract string ParamPrefix { get; }

        public abstract string LeftToken { get; }

        public abstract string RightToken { get; }

        #endregion
    }
}
